package com.sias.judgeservice.judge.strategy;

import cn.hutool.json.JSONUtil;
import com.sias.model.model.codsandbox.JudgeInfo;
import com.sias.model.model.dto.question.JudgeCase;
import com.sias.model.model.dto.question.JudgeConfig;
import com.sias.model.model.entity.Question;
import com.sias.model.model.enums.JudgeInfoMessageEnum;

import java.util.List;
import java.util.Optional;

/**
 * @author 吴文杰
 * @version 1.0
 * @since 2023/12/10 20:50
 */
public class JavaLanguageJudgeStrategy implements JudgeStrategy {
  @Override
  public JudgeInfo doJudge(JudgeContext judgeContext) {
    JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
    Long memory = Optional.ofNullable(judgeInfo.getMemory()).orElse(0L);
    Long time = Optional.ofNullable(judgeInfo.getTime()).orElse(0L);
    List<String> inputList = judgeContext.getInputList();
    List<String> outputList = judgeContext.getOutputList();
    Question question = judgeContext.getQuestion();
    List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
    JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPTED;
    JudgeInfo judgeInfoResponse = new JudgeInfo();
    judgeInfoResponse.setMemory(memory);
    judgeInfoResponse.setTime(time);
    // 先判断沙箱执行的结果输出数量是否和预期输出数量相等
    if (outputList.size() != inputList.size()) {
      judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
      judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
      return judgeInfoResponse;
    }
    // 依次判断每一项输出和预期输出是否相等
    for (int i = 0; i < judgeCaseList.size(); i++) {
      JudgeCase judgeCase = judgeCaseList.get(i);
      if (!judgeCase.getOutput().equals(outputList.get(i))) {
        judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
        judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
        return judgeInfoResponse;
      }
    }
    // 判断题目限制
    String judgeConfigStr = question.getJudgeConfig();
    JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);
    Long needMemoryLimit = judgeConfig.getMemoryLimit();
    Long needTimeLimit = judgeConfig.getTimeLimit();
    if (memory > needMemoryLimit) {
      judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;
      judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
      return judgeInfoResponse;
    }
    // Java 程序本身需要额外执行 10 秒钟
    long JAVA_PROGRAM_TIME_COST = 10000L;
    if ((time - JAVA_PROGRAM_TIME_COST) > needTimeLimit) {
      judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;
      judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
      return judgeInfoResponse;
    }
    judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
    return judgeInfoResponse;
  }
}

/**
 * JudgeInfo judgeInfoResponse = new JudgeInfo();
 * <p>
 * JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
 * List<String> inputList = judgeContext.getInputList();
 * List<String> outputList = judgeContext.getOutputList();
 * List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
 * Question question = judgeContext.getQuestion();
 * <p>
 * <p>
 * Long memory = judgeInfo.getMemory();
 * Long time = judgeInfo.getTime();
 * <p>
 * <p>
 * judgeInfoResponse.setMemory(memory);
 * judgeInfoResponse.setTime(time);
 * <p>
 * // 判题结果初始状态
 * JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPTED;
 * <p>
 * // 输出结果数量是否相等
 * if (outputList.size() != inputList.size()) {
 * judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
 * judgeInfoResponse.setMessage(judgeInfoMessageEnum.getText());
 * return judgeInfoResponse;
 * }
 * // 遍历结果比较是否相等
 * for (int i = 0; i < outputList.size(); i++) {
 * JudgeCase judgeCase = judgeCaseList.get(i);
 * if (!judgeCase.getOutput().equals(outputList.get(i))) {
 * judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
 * judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
 * return judgeInfoResponse;
 * }
 * }
 * String judgeConfigStr = question.getJudgeConfig();
 * JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);
 * Long timeLimit = judgeConfig.getTimeLimit();
 * Long memoryLimit = judgeConfig.getMemoryLimit();
 * if (memory > memoryLimit) {
 * judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;
 * judgeInfoResponse.setMessage(judgeInfoMessageEnum.getText());
 * return judgeInfoResponse;
 * }
 * // Java 程序本身需要额外执行 10 秒钟
 * long JAVA_PROGRAM_TIME_COST = 10000L;
 * if (time - JAVA_PROGRAM_TIME_COST > timeLimit) {
 * judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;
 * judgeInfoResponse.setMessage(judgeInfoMessageEnum.getText());
 * return judgeInfoResponse;
 * }
 * judgeInfoResponse.setMessage(judgeInfoMessageEnum.getText());
 * return judgeInfoResponse;
 * // }
 * }
 */
